{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Function calling\n",
    "\n",
    "A growing number of chat models, like [OpenAI](/docs/integrations/chat/openai#tool-calling), [Mistral](/docs/integrations/chat/mistral#tool-calling), etc., have a function-calling\n",
    "API that lets you describe functions and their arguments, and have the model return a JSON object with a function to invoke and the inputs to that function.\n",
    "Function-calling is extremely useful for building [tool-using chains and agents](/docs/use_cases/tool_use/), and for getting structured outputs from models more generally.\n",
    "\n",
    "LangChain comes with a number of utilities to make function-calling easy. Namely, it comes with:\n",
    "\n",
    "- simple syntax for binding functions to models\n",
    "- converters for formatting various types of objects to the expected function schemas\n",
    "- output parsers for extracting the function invocations from API responses\n",
    "- chains for getting structured outputs from a model, built on top of function calling\n",
    "\n",
    "We'll focus here on the first two points. For a detailed guide on output parsing check out the [OpenAI Tools output parsers](/docs/modules/model_io/output_parsers/types/openai_tools) and to\n",
    "see the structured output chains check out the Structured output guide ([OpenAI](/docs/integrations/chat/openai#withstructuredoutput--), [Mistral](/docs/integrations/chat/mistral#withstructuredoutput--)).\n",
    "\n",
    "Before getting started make sure you have `@langchain/core` installed."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```{=mdx}\n",
    "import IntegrationInstallTooltip from \"@mdx_components/integration_install_tooltip.mdx\";\n",
    "import Npm2Yarn from \"@theme/Npm2Yarn\";\n",
    "\n",
    "<IntegrationInstallTooltip></IntegrationInstallTooltip>\n",
    "\n",
    "<Npm2Yarn>\n",
    "  @langchain/core\n",
    "</Npm2Yarn>\n",
    "```\n",
    "\n",
    "We'll also use `zod-to-json-schema` frequently throughout this doc for converting Zod schemas to JSON schemas. Make sure you have it installed:\n",
    "\n",
    "```{=mdx}\n",
    "<Npm2Yarn>\n",
    "  zod-to-json-schema\n",
    "</Npm2Yarn>\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A number of models implement helper methods that will take care of formatting and binding different function-like objects to the model.\n",
    "Let's take a look at how we might take the following Zod function schema and get different models to invoke it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import { z } from \"zod\";\n",
    "\n",
    "/**\n",
    " * Note that the descriptions here are crucial, as they will be passed along\n",
    " * to the model along with the class name.\n",
    " */\n",
    "const calculatorSchema = z.object({\n",
    "  operation: z\n",
    "    .enum([\"add\", \"subtract\", \"multiply\", \"divide\"])\n",
    "    .describe(\"The type of operation to execute.\"),\n",
    "  number1: z.number().describe(\"The first number to operate on.\"),\n",
    "  number2: z.number().describe(\"The second number to operate on.\"),\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<Tabs>\n",
    "\n",
    "  <TabItem value=\"openai\" label=\"OpenAI\" default>\n",
    "\n",
    "Set up dependencies and API keys:\n",
    "\n",
    "```bash\n",
    "npm install @langchain/openai\n",
    "```\n",
    "\n",
    "```bash\n",
    "OPENAI_API_KEY=your-api-key\n",
    "```\n",
    "\n",
    "We can use the `ChatOpenAI.bind()` method to handle converting `calculatorSchema` to an OpenAI function and binding it to the model (i.e., passing it in each time the model is invoked)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage {\n",
       "  lc_serializable: \u001b[33mtrue\u001b[39m,\n",
       "  lc_kwargs: {\n",
       "    content: \u001b[32m\"\"\u001b[39m,\n",
       "    additional_kwargs: {\n",
       "      function_call: \u001b[90mundefined\u001b[39m,\n",
       "      tool_calls: [\n",
       "        {\n",
       "          id: \u001b[32m\"call_cLBi7NjrehSEPoXr21i08NER\"\u001b[39m,\n",
       "          type: \u001b[32m\"function\"\u001b[39m,\n",
       "          function: \u001b[36m[Object]\u001b[39m\n",
       "        }\n",
       "      ]\n",
       "    }\n",
       "  },\n",
       "  lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n",
       "  content: \u001b[32m\"\"\u001b[39m,\n",
       "  name: \u001b[90mundefined\u001b[39m,\n",
       "  additional_kwargs: {\n",
       "    function_call: \u001b[90mundefined\u001b[39m,\n",
       "    tool_calls: [\n",
       "      {\n",
       "        id: \u001b[32m\"call_cLBi7NjrehSEPoXr21i08NER\"\u001b[39m,\n",
       "        type: \u001b[32m\"function\"\u001b[39m,\n",
       "        function: {\n",
       "          name: \u001b[32m\"calculator\"\u001b[39m,\n",
       "          arguments: \u001b[32m'{\"operation\":\"multiply\",\"number1\":3,\"number2\":12}'\u001b[39m\n",
       "        }\n",
       "      }\n",
       "    ]\n",
       "  }\n",
       "}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import { ChatOpenAI } from \"@langchain/openai\";\n",
    "import { zodToJsonSchema } from \"zod-to-json-schema\";\n",
    "\n",
    "const llm = new ChatOpenAI({\n",
    "  modelName: \"gpt-3.5-turbo-0125\",\n",
    "  temperature: 0,\n",
    "});\n",
    "const llmWithTools = llm.bind({\n",
    "  tools: [\n",
    "    {\n",
    "      type: \"function\" as const,\n",
    "      function: {\n",
    "        name: \"calculator\",\n",
    "        description: \"A simple calculator tool\",\n",
    "        parameters: zodToJsonSchema(calculatorSchema),\n",
    "      },\n",
    "    },\n",
    "  ],\n",
    "});\n",
    "await llmWithTools.invoke(\"What is 3 * 12\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "> #### See the LangSmith trace [here](https://smith.langchain.com/public/cb36c6e5-e478-463c-801a-0c1b09ace04d/r).\n",
    "\n",
    "We can add a tool parser to extract the tool calls from the generated message to JSON:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[\n",
       "  {\n",
       "    type: \u001b[32m\"calculator\"\u001b[39m,\n",
       "    args: { operation: \u001b[32m\"multiply\"\u001b[39m, number1: \u001b[33m3\u001b[39m, number2: \u001b[33m12\u001b[39m }\n",
       "  }\n",
       "]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import { JsonOutputToolsParser } from \"@langchain/core/output_parsers/openai_tools\";\n",
    "\n",
    "const toolChain = llmWithTools.pipe(new JsonOutputToolsParser());\n",
    "await toolChain.invoke(\"What is 3 * 12\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "> #### See the LangSmith trace [here](https://smith.langchain.com/public/e2a3f796-0c8a-404b-8d90-e8a626242a24/r).\n",
    "\n",
    "\n",
    "If we wanted to force that a tool is used (and that it is used only once), we can set the `tool_choice` argument:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage {\n",
       "  lc_serializable: \u001b[33mtrue\u001b[39m,\n",
       "  lc_kwargs: {\n",
       "    content: \u001b[32m\"\"\u001b[39m,\n",
       "    additional_kwargs: {\n",
       "      function_call: \u001b[90mundefined\u001b[39m,\n",
       "      tool_calls: [\n",
       "        {\n",
       "          id: \u001b[32m\"call_6Zh6rnj4W8pvfrOxzc4720Pw\"\u001b[39m,\n",
       "          type: \u001b[32m\"function\"\u001b[39m,\n",
       "          function: \u001b[36m[Object]\u001b[39m\n",
       "        }\n",
       "      ]\n",
       "    }\n",
       "  },\n",
       "  lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n",
       "  content: \u001b[32m\"\"\u001b[39m,\n",
       "  name: \u001b[90mundefined\u001b[39m,\n",
       "  additional_kwargs: {\n",
       "    function_call: \u001b[90mundefined\u001b[39m,\n",
       "    tool_calls: [\n",
       "      {\n",
       "        id: \u001b[32m\"call_6Zh6rnj4W8pvfrOxzc4720Pw\"\u001b[39m,\n",
       "        type: \u001b[32m\"function\"\u001b[39m,\n",
       "        function: {\n",
       "          name: \u001b[32m\"calculator\"\u001b[39m,\n",
       "          arguments: \u001b[32m'{\"operation\":\"multiply\",\"number1\":3,\"number2\":12}'\u001b[39m\n",
       "        }\n",
       "      }\n",
       "    ]\n",
       "  }\n",
       "}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "const llmWithMultiply = llm.bind({\n",
    "  tools: [\n",
    "    {\n",
    "      type: \"function\" as const,\n",
    "      function: {\n",
    "        name: \"calculator\",\n",
    "        description: \"A simple calculator tool\",\n",
    "        parameters: zodToJsonSchema(calculatorSchema),\n",
    "      },\n",
    "    },\n",
    "  ],\n",
    "  tool_choice: {\n",
    "    type: \"function\" as const,\n",
    "    function: {\n",
    "      name: \"calculator\",\n",
    "    },\n",
    "  },\n",
    "});\n",
    "await llmWithMultiply.invoke(\"What is 3 * 12\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "</TabItem>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "  <TabItem value=\"mistralai\" label=\"MistralAI\">\n",
    "\n",
    "Set up dependencies and API keys:\n",
    "\n",
    "```bash\n",
    "npm install @langchain/mistralai\n",
    "```\n",
    "\n",
    "```bash\n",
    "MISTRALAI_API_KEY=your-api-key\n",
    "```\n",
    "\n",
    "We can use the `ChatMistralAI.bind()` method to handle converting `calculatorSchema` to a function and binding it to the model (i.e., passing it in each time the model is invoked)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage {\n",
       "  lc_serializable: \u001b[33mtrue\u001b[39m,\n",
       "  lc_kwargs: {\n",
       "    content: \u001b[32m\"\"\u001b[39m,\n",
       "    additional_kwargs: {\n",
       "      tool_calls: [ { id: \u001b[32m\"null\"\u001b[39m, type: \u001b[32m\"function\"\u001b[39m, function: \u001b[36m[Object]\u001b[39m } ]\n",
       "    }\n",
       "  },\n",
       "  lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n",
       "  content: \u001b[32m\"\"\u001b[39m,\n",
       "  name: \u001b[90mundefined\u001b[39m,\n",
       "  additional_kwargs: {\n",
       "    tool_calls: [\n",
       "      {\n",
       "        id: \u001b[32m\"null\"\u001b[39m,\n",
       "        type: \u001b[32m\"function\"\u001b[39m,\n",
       "        function: {\n",
       "          name: \u001b[32m\"calculator\"\u001b[39m,\n",
       "          arguments: \u001b[32m'{\"operation\": \"multiply\", \"number1\": 3, \"number2\": 12}'\u001b[39m\n",
       "        }\n",
       "      }\n",
       "    ]\n",
       "  }\n",
       "}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import { ChatMistralAI } from \"@langchain/mistralai\";\n",
    "import { zodToJsonSchema } from \"zod-to-json-schema\";\n",
    "\n",
    "const llm = new ChatMistralAI({\n",
    "  modelName: \"mistral-large-latest\",\n",
    "  temperature: 0,\n",
    "});\n",
    "const llmWithTools = llm.bind({\n",
    "  tools: [\n",
    "    {\n",
    "      type: \"function\" as const,\n",
    "      function: {\n",
    "        name: \"calculator\",\n",
    "        description: \"A simple calculator tool\",\n",
    "        parameters: zodToJsonSchema(calculatorSchema),\n",
    "      },\n",
    "    },\n",
    "  ],\n",
    "});\n",
    "await llmWithTools.invoke(\"What is 3 * 12\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "> #### See the LangSmith trace [here](https://smith.langchain.com/public/ea36cd94-ff85-4972-a087-e5ac6d927141/r).\n",
    "\n",
    "We can add a tool parser to extract the tool calls from the generated message to JSON:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[\n",
       "  {\n",
       "    type: \u001b[32m\"calculator\"\u001b[39m,\n",
       "    args: { operation: \u001b[32m\"multiply\"\u001b[39m, number1: \u001b[33m3\u001b[39m, number2: \u001b[33m12\u001b[39m }\n",
       "  }\n",
       "]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import { JsonOutputToolsParser } from \"@langchain/core/output_parsers/openai_tools\";\n",
    "\n",
    "const toolChain = llmWithTools.pipe(new JsonOutputToolsParser());\n",
    "await toolChain.invoke(\"What is 3 * 12\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "> #### See the LangSmith trace [here](https://smith.langchain.com/public/05893756-0689-4d38-933f-529920f86dbb/r).\n",
    "\n",
    "\n",
    "\n",
    "  </TabItem>\n",
    "  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "  <TabItem value=\"togetherai\" label=\"TogetherAI\">\n",
    "\n",
    "Set up dependencies and API keys:\n",
    "\n",
    "```bash\n",
    "npm install @langchain/community\n",
    "```\n",
    "\n",
    "```bash\n",
    "TOGETHER_AI_API_KEY=your-api-key\n",
    "```\n",
    "\n",
    "We can use the `ChatTogetherAI.bind()` method to handle converting `calculatorSchema` to a function and binding it to the model (i.e., passing it in each time the model is invoked).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage {\n",
       "  lc_serializable: \u001b[33mtrue\u001b[39m,\n",
       "  lc_kwargs: {\n",
       "    content: \u001b[32m\"\"\u001b[39m,\n",
       "    additional_kwargs: {\n",
       "      function_call: \u001b[90mundefined\u001b[39m,\n",
       "      tool_calls: [\n",
       "        {\n",
       "          id: \u001b[32m\"call_97uau7pkgam7n25q19fq4htp\"\u001b[39m,\n",
       "          type: \u001b[32m\"function\"\u001b[39m,\n",
       "          function: \u001b[36m[Object]\u001b[39m\n",
       "        }\n",
       "      ]\n",
       "    }\n",
       "  },\n",
       "  lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n",
       "  content: \u001b[32m\"\"\u001b[39m,\n",
       "  name: \u001b[90mundefined\u001b[39m,\n",
       "  additional_kwargs: {\n",
       "    function_call: \u001b[90mundefined\u001b[39m,\n",
       "    tool_calls: [\n",
       "      {\n",
       "        id: \u001b[32m\"call_97uau7pkgam7n25q19fq4htp\"\u001b[39m,\n",
       "        type: \u001b[32m\"function\"\u001b[39m,\n",
       "        function: {\n",
       "          name: \u001b[32m\"calculator\"\u001b[39m,\n",
       "          arguments: \u001b[32m'{\"operation\":\"multiply\",\"number1\":3,\"number2\":12}'\u001b[39m\n",
       "        }\n",
       "      }\n",
       "    ]\n",
       "  }\n",
       "}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import { ChatTogetherAI } from \"@langchain/community/chat_models/togetherai\";\n",
    "import { zodToJsonSchema } from \"zod-to-json-schema\";\n",
    "\n",
    "const llm = new ChatTogetherAI({\n",
    "  modelName: \"mistralai/Mixtral-8x7B-Instruct-v0.1\",\n",
    "  temperature: 0,\n",
    "});\n",
    "const llmWithTools = llm.bind({\n",
    "  tools: [\n",
    "    {\n",
    "      type: \"function\" as const,\n",
    "      function: {\n",
    "        name: \"calculator\",\n",
    "        description: \"A simple calculator tool\",\n",
    "        parameters: zodToJsonSchema(calculatorSchema),\n",
    "      },\n",
    "    },\n",
    "  ],\n",
    "});\n",
    "await llmWithTools.invoke(\"What is 3 * 12\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "> #### See the LangSmith trace [here](https://smith.langchain.com/public/bf416507-a583-41e9-b262-cef219f3c803/r).\n",
    "\n",
    "\n",
    "We can add a tool parser to extract the tool calls from the generated message to JSON:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[\n",
       "  {\n",
       "    type: \u001b[32m\"calculator\"\u001b[39m,\n",
       "    args: { operation: \u001b[32m\"multiply\"\u001b[39m, number1: \u001b[33m3\u001b[39m, number2: \u001b[33m12\u001b[39m }\n",
       "  }\n",
       "]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import { JsonOutputToolsParser } from \"@langchain/core/output_parsers/openai_tools\";\n",
    "\n",
    "const toolChain = llmWithTools.pipe(new JsonOutputToolsParser());\n",
    "await toolChain.invoke(\"What is 3 * 12\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "> #### See the LangSmith trace [here](https://smith.langchain.com/public/79ff4cf0-2a72-440e-a020-cec9213d5839/r).\n",
    "\n",
    "\n",
    "If we wanted to force that a tool is used (and that it is used only once), we can set the `tool_choice` argument:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage {\n",
       "  lc_serializable: \u001b[33mtrue\u001b[39m,\n",
       "  lc_kwargs: {\n",
       "    content: \u001b[32m\"\"\u001b[39m,\n",
       "    additional_kwargs: {\n",
       "      function_call: \u001b[90mundefined\u001b[39m,\n",
       "      tool_calls: [\n",
       "        {\n",
       "          id: \u001b[32m\"call_vcc7nar0r2doz26jnnsojlls\"\u001b[39m,\n",
       "          type: \u001b[32m\"function\"\u001b[39m,\n",
       "          function: \u001b[36m[Object]\u001b[39m\n",
       "        }\n",
       "      ]\n",
       "    }\n",
       "  },\n",
       "  lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n",
       "  content: \u001b[32m\"\"\u001b[39m,\n",
       "  name: \u001b[90mundefined\u001b[39m,\n",
       "  additional_kwargs: {\n",
       "    function_call: \u001b[90mundefined\u001b[39m,\n",
       "    tool_calls: [\n",
       "      {\n",
       "        id: \u001b[32m\"call_vcc7nar0r2doz26jnnsojlls\"\u001b[39m,\n",
       "        type: \u001b[32m\"function\"\u001b[39m,\n",
       "        function: {\n",
       "          name: \u001b[32m\"calculator\"\u001b[39m,\n",
       "          arguments: \u001b[32m'{\"operation\":\"multiply\",\"number1\":3,\"number2\":12}'\u001b[39m\n",
       "        }\n",
       "      }\n",
       "    ]\n",
       "  }\n",
       "}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "const llmWithMultiply = llm.bind({\n",
    "  tools: [\n",
    "    {\n",
    "      type: \"function\" as const,\n",
    "      function: {\n",
    "        name: \"calculator\",\n",
    "        description: \"A simple calculator tool\",\n",
    "        parameters: zodToJsonSchema(calculatorSchema),\n",
    "      },\n",
    "    },\n",
    "  ],\n",
    "  tool_choice: {\n",
    "    type: \"function\" as const,\n",
    "    function: {\n",
    "      name: \"calculator\",\n",
    "    },\n",
    "  },\n",
    "});\n",
    "await llmWithMultiply.invoke(\"What is 3 * 12\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "  </TabItem>\n",
    "\n",
    "</Tabs>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Defining functions schemas\n",
    "\n",
    "In case you need to access function schemas directly, LangChain has a built-in converter that can turn Zod schemas with LangChain tools into the OpenAI format JSON schema:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{\n",
       "  type: \u001b[32m\"function\"\u001b[39m,\n",
       "  function: {\n",
       "    name: \u001b[32m\"calculator\"\u001b[39m,\n",
       "    description: \u001b[32m\"A simple calculator tool\"\u001b[39m,\n",
       "    parameters: {\n",
       "      type: \u001b[32m\"object\"\u001b[39m,\n",
       "      properties: {\n",
       "        operation: {\n",
       "          type: \u001b[32m\"string\"\u001b[39m,\n",
       "          enum: \u001b[36m[Array]\u001b[39m,\n",
       "          description: \u001b[32m\"The type of operation to execute.\"\u001b[39m\n",
       "        },\n",
       "        number1: {\n",
       "          type: \u001b[32m\"number\"\u001b[39m,\n",
       "          description: \u001b[32m\"The first number to operate on.\"\u001b[39m\n",
       "        },\n",
       "        number2: {\n",
       "          type: \u001b[32m\"number\"\u001b[39m,\n",
       "          description: \u001b[32m\"The second number to operate on.\"\u001b[39m\n",
       "        }\n",
       "      },\n",
       "      required: [ \u001b[32m\"operation\"\u001b[39m, \u001b[32m\"number1\"\u001b[39m, \u001b[32m\"number2\"\u001b[39m ],\n",
       "      additionalProperties: \u001b[33mfalse\u001b[39m,\n",
       "      \u001b[32m\"$schema\"\u001b[39m: \u001b[32m\"http://json-schema.org/draft-07/schema#\"\u001b[39m\n",
       "    }\n",
       "  }\n",
       "}"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import { StructuredTool } from \"@langchain/core/tools\";\n",
    "import { convertToOpenAITool } from \"@langchain/core/utils/function_calling\";\n",
    "import { z } from \"zod\";\n",
    "\n",
    "const calculatorSchema = z.object({\n",
    "  operation: z\n",
    "    .enum([\"add\", \"subtract\", \"multiply\", \"divide\"])\n",
    "    .describe(\"The type of operation to execute.\"),\n",
    "  number1: z.number().describe(\"The first number to operate on.\"),\n",
    "  number2: z.number().describe(\"The second number to operate on.\"),\n",
    "});\n",
    "\n",
    "class CalculatorTool extends StructuredTool {\n",
    "  schema = calculatorSchema;\n",
    "\n",
    "  name = \"calculator\";\n",
    "\n",
    "  description = \"A simple calculator tool\";\n",
    "\n",
    "  async _call(params: z.infer<typeof calculatorSchema>) {\n",
    "    return \"The answer\";\n",
    "  }\n",
    "}\n",
    "\n",
    "const asOpenAITool = convertToOpenAITool(new CalculatorTool());\n",
    "\n",
    "asOpenAITool;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Next steps\n",
    "\n",
    "- **Output parsing**: See [OpenAI Tools output parsers](/docs/modules/model_io/output_parsers/types/openai_tools) to learn about extracting the function calling API responses into various formats.\n",
    "- **Structured output chains**: Some models have constructors that handle creating a structured output chain for you ([OpenAI](/docs/integrations/chat/openai#withstructuredoutput--), [Mistral](/docs/integrations/chat/mistral#withstructuredoutput--)).\n",
    "- **Tool use**: See how to construct chains and agents that actually call the invoked tools in [these guides](/docs/use_cases/tool_use/).\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Deno",
   "language": "typescript",
   "name": "deno"
  },
  "language_info": {
   "file_extension": ".ts",
   "mimetype": "text/x.typescript",
   "name": "typescript",
   "nb_converter": "script",
   "pygments_lexer": "typescript",
   "version": "5.3.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
